﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ADIGRE.Domain;
using ADIGRE.MVC3.Web.Controllers.ViewModels;
using ADIGRE.MVC3.Web.Util;
using SharpArch.NHibernate.Contracts.Repositories;
using ADIGRE.Infrastructure.Queries.Authentication;
using SharpArch.NHibernate.Web.Mvc;
using ADIGRE.Infrastructure.Queries.Pessoa;
using ADIGRE.Infrastructure.Queries.Entrada;
using ADIGRE.Infrastructure.Queries.Receita;
using ADIGRE.Domain.RoutineTable;

namespace ADIGRE.MVC3.Web.Controllers
{

    public class EntradaController : ControllerAuthorize
    {
        private readonly IAuthenticationService _authenticationService;
        private readonly INHibernateRepository<Pessoa> _PessoaRepository;
        private readonly INHibernateRepository<Receita> _ReceitaRepository;
        private readonly INHibernateRepository<Oferta> _OfertaRepository;
        private readonly INHibernateRepository<Entrada> _EntradaRepository;
        private readonly INHibernateRepository<Dizimo> _DizimoRepository;
        private readonly INHibernateRepository<BalancoMensal> _BalancoMensal;
        private readonly IPessoaQuery _PessoaQueryRepository;
        private readonly IReceitaQuery _ReceitaQueryRepository;

        public EntradaController(IAuthenticationService authenticationService, INHibernateRepository<BalancoMensal> BalancoMensal,
            INHibernateRepository<Entrada> EntradaRepository, INHibernateRepository<Dizimo> _DizimoRepository, INHibernateRepository<Oferta> OfertaRepository,
            INHibernateRepository<Receita> ReceitaRepository, IReceitaQuery ReceitaQueryRepository,
            INHibernateRepository<Pessoa> PessoaRepository, IPessoaQuery PessoaQueryRepository)
        {
            this._authenticationService = authenticationService;
            this._ReceitaRepository = ReceitaRepository;
            this._ReceitaQueryRepository = ReceitaQueryRepository;
            this._PessoaRepository = PessoaRepository;
            this._PessoaQueryRepository = PessoaQueryRepository;
            this._OfertaRepository = OfertaRepository;
            this._EntradaRepository = EntradaRepository;
            this._DizimoRepository = _DizimoRepository;
            this._BalancoMensal = BalancoMensal;
        }

        public ActionResult Index()
        {
            try
            {

                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;
                ViewBag.IsRoot = user.IsRoot;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
                var list = _EntradaRepository.GetAll().Where(x => !x.IsExcluido).OrderByDescending(x => x.DtLancamento);

                List<EntradaViewModel> Entradas = new List<EntradaViewModel>();

                foreach (var data in list.Select(x => x.DtLancamento).Distinct())
                {
                    EntradaViewModel entrada = new EntradaViewModel();
                    entrada.DtCulto = data;
                    entrada.VlOfertas = list.Where(x => x.DtLancamento == data && x.EnumLancamento == EnumLancamento.Oferta).Sum(x => x.VlLancamento);
                    entrada.VlDizimos = list.Where(x => x.DtLancamento == data && x.EnumLancamento == EnumLancamento.Dizimo).Sum(x => x.VlLancamento);
                    entrada.Dizimos = new List<Dizimo>();

                    foreach (Dizimo item in list.Where(x => x.DtLancamento == data && x.EnumLancamento == EnumLancamento.Dizimo))
                        entrada.Dizimos.Add(_DizimoRepository.Get(item.Id));
                    entrada.Dizimos = entrada.Dizimos.OrderBy(x => x.Dizimista.NmPessoa).ToList();
                    Entradas.Add(entrada);
                }

                return View(Entradas);
            }
            catch (Exception ex)
            {
                _ObjLog.Error("EntradaController(Index): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
            }
            return RedirectToAction("Index", "Home");
        }

        public ActionResult Culto()
        {
            try
            {
                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
                    if(!(user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Tesoureiro)))
                        return RedirectToAction("Index","Home");
                CultoViewModel culto = new CultoViewModel();
                var dtRetroativa = _BalancoMensal.GetAll().Max(x => x.DtPeriodo);
                if (dtRetroativa.HasValue)
                    culto.DtRetroativa = dtRetroativa.Value.AddMonths(1).AddDays(-1);

                var combo = new ComboListItem();
                List<Pessoa> pessoas = this._PessoaQueryRepository.GelAllPessoa().ToList();
                ViewBag.Dizimistas = combo.ComboPessoas(pessoas);
                return View(culto);
            }
            catch (Exception ex)
            {
                _ObjLog.Error("EntradaController(Culto): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
            }
            return RedirectToAction("Index", "Home");
        }

        [HttpPost]
        [Transaction]
        public ActionResult Culto(FormCollection collection)
        {
            bool Invalid = false;
            CultoViewModel culto = new CultoViewModel();

            try
            {
                TryUpdateModel(culto, collection);
                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
                if (!(user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Tesoureiro)))
                    return RedirectToAction("Index", "Home");

                if (!culto.Oferta.DtLancamento.HasValue)
                {
                    ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_CULTO_DATA);
                    Invalid = true;
                }
                else if (culto.DtRetroativa.HasValue && culto.DtRetroativa.Value.Date == culto.Oferta.DtLancamento.Value.Date)
                {
                    Invalid = true;
                    ModelState.AddModelError("", GlobalResources.Sistema.Feedback.WARNING_DATA_RETROATIVA);
                }

                if (culto.Oferta.VlLancamento < 0)
                {
                    ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_OFERTA_VALOR);
                    Invalid = true;
                }

                foreach (var dizimo in culto.Dizimos)
                {
                    if (!dizimo.IsExcluido)
                    {
                        if (dizimo.VlLancamento <= 0)
                        {
                            ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_DIZIMO_VALOR);
                            Invalid = true;
                        }
                        if (!dizimo.DtReferencia.HasValue && culto.Oferta.DtLancamento.HasValue)
                        {
                            dizimo.DtReferencia = culto.Oferta.DtLancamento;
                            dizimo.DtLancamento = culto.Oferta.DtLancamento;
                        }
                        else if (!dizimo.DtReferencia.HasValue)
                        {
                            ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_DIZIMO_DATA);
                            Invalid = true;
                        }
                    }
                }

                if (Invalid)
                {
                    var combo = new ComboListItem();
                    List<Pessoa> pessoas = _PessoaQueryRepository.GelAllPessoa().ToList();
                    ViewBag.Dizimistas = combo.ComboPessoas(pessoas);

                    return View(culto);
                }

                culto.Oferta.ValidarOferta(user);
                if (culto.Oferta.Id > 0)
                {
                    var oferta = _OfertaRepository.Get(culto.Oferta.Id);
                    oferta.Complete(culto.Oferta);
                    culto.Oferta = oferta;
                }
                _OfertaRepository.SaveOrUpdate(culto.Oferta);

                foreach (var dizimo in culto.Dizimos)
                {
                    if (!dizimo.IsExcluido)
                    {
                        dizimo.ValidarDizimo(user, culto.Oferta.DtLancamento);
                        if (dizimo.Id > 0)
                        {
                            var d = _DizimoRepository.Get(dizimo.Id);
                            d.Complete(dizimo);
                            _DizimoRepository.SaveOrUpdate(d);
                        }
                        else
                        {
                            _DizimoRepository.Save(dizimo);
                        }
                    }
                }
                _Feedback = GlobalResources.Sistema.Feedback.SUCCESS_CADASTRO;
                return RedirectToAction("Index");
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_INVALID_DATA + ": " + ex.Message);
                _ObjLog.Error("EntradaController(Culto[]): " + ex.ToString());
            }

            return View(culto);
        }

        public ActionResult AddDizimo()
        {
            try
            {
                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
                if (!(user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Tesoureiro)))
                    return RedirectToAction("Index", "Home");

                CultoViewModel culto = new CultoViewModel();
                var collection = new FormCollection(Request.QueryString);
                TryUpdateModel(culto, collection);

                var combo = new ComboListItem();
                List<Pessoa> pessoas = _PessoaQueryRepository.GelAllPessoa().ToList();
                ViewBag.Dizimistas = combo.ComboPessoas(pessoas);

                if (culto.Dizimos == null)
                    culto.Dizimos = new List<Dizimo>();
                culto.Dizimos.Add(new Dizimo());

                return View("_DizimosCulto", culto);
            }
            catch (Exception ex)
            {
                _ObjLog.Error("EntradaController(AddDizimo): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
            }
            return View("_DizimosCulto", new CultoViewModel());
        }

    }
}
